﻿using Corina.Cydee.DataService;
using Corina.Infrastructure;
using System;
using System.Net;
using System.ServiceModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Collections.Generic;
using Corina.Enumerations;
using Corina.Common;
using System.Windows.Resources;
using System.IO;
using System.Windows.Markup;
using System.Linq;
using Corina.Commands;
using System.Net.NetworkInformation;
using System.ComponentModel;
using System.Reflection;

namespace Corina.Cydee.Apphub.Viewmodels
{
    public class ViewmodelBase : BaseClass
    {
        protected DataContainer DataContext
        {
            get
            {
                if(IsDesignMode)
                {
                    return new DataContainer();
                }
                return (DataContainer)((MainPage)App.Current.RootVisual).DataContext;
            }
        }

        public string WebServiceAddress
        {
            get
            {
                if(IsDesignMode)
                {
                    return "http://www.byshuju.cn:8080/";
                }
                if(Application.Current.IsRunningOutOfBrowser)
                {
                    return "http://www.byshuju.cn:8080/";
                }
                return Application.Current.Resources["WebServiceAddress"] as string;
            }
        }

        #region Soap Clients
        protected CoreSoapClient CoreClient { get; set; }
        protected WeburlSoapClient WeburlClient { get; set; }
        protected ManagerSoapClient ManagerClient { get; set; }
        protected CommonBaseSoapClient CommonBaseClient { get; set; }
        protected DeviceSoapClient DeviceClient { get; set; }
        protected UserSoapClient UserClient { get; set; }
        protected AreaSoapClient AreaClient { get; set; }
        protected DeviceMeasureSoapClient DeviceMeasureClient { get; set; }
        protected UploaderSoapClient UploaderClient { get; set; }
        protected DocumentsSoapClient DocumentClient { get; set; }
        #endregion

        public ViewmodelBase()
        {
            NetworkChange.NetworkAddressChanged += NetworkAddressChanged;

            CoreClient = new CoreSoapClient(WebBindingConfig.HttpBinding, new EndpointAddress(WebServiceAddress+ ConstUrls.URL_CORE));
            WeburlClient = new WeburlSoapClient(WebBindingConfig.HttpBinding, new EndpointAddress(WebServiceAddress + ConstUrls.URL_WEBURL));
            ManagerClient = new ManagerSoapClient(WebBindingConfig.HttpBinding, new EndpointAddress(WebServiceAddress + ConstUrls.URL_MANAGER));
            CommonBaseClient = new CommonBaseSoapClient(WebBindingConfig.HttpBinding, new EndpointAddress(WebServiceAddress + ConstUrls.URL_COMMONBASE));
            DeviceClient = new DeviceSoapClient(WebBindingConfig.HttpBinding, new EndpointAddress(WebServiceAddress + ConstUrls.URL_DEVICE));
            UserClient = new UserSoapClient(WebBindingConfig.HttpBinding, new EndpointAddress(WebServiceAddress + ConstUrls.URL_USER));
            AreaClient = new AreaSoapClient(WebBindingConfig.HttpBinding, new EndpointAddress(WebServiceAddress + ConstUrls.URL_AREA));
            DeviceMeasureClient = new DeviceMeasureSoapClient(WebBindingConfig.HttpBinding, new EndpointAddress(WebServiceAddress + ConstUrls.URL_DEVICEMEASURE));
            UploaderClient = new UploaderSoapClient(WebBindingConfig.HttpBinding, new EndpointAddress(WebServiceAddress + ConstUrls.URL_UPLOADER));
            DocumentClient = new DocumentsSoapClient(WebBindingConfig.HttpBinding, new EndpointAddress(WebServiceAddress + ConstUrls.URL_DOCUMENTS));
        }

        private void NetworkAddressChanged(object sender, EventArgs e)
        {
            NetworkChanged();
        }

        #region Virtual Methods
        protected virtual void LoadData(params object[] paras)
        { }

        protected virtual void OperationChanged()
        {
            RaisePropertyChanged(() => ShowUpdate);
        }

        protected virtual void CurrentIndexChanged()
        {
            LoadData();
        } 

        protected virtual void NetworkChanged()
        {

        }

        protected virtual string GetOperateResult(ResultValue result)
        {
            string key = "IDS_OPERATE_RESULT_" + result.ToString().ToUpper();
            if (Application.Current.Resources.Contains(key))
            {
                return (string)Application.Current.Resources[key];
            }
            else
            {
                return result.ToString();
            }
        }

        protected virtual MessageBoxResult ShowConfirm(string key)
        {
            string content = Application.Current.Resources[key] as string;
            return MessageBox.Show(content, "确认", MessageBoxButton.OKCancel);
        }

        protected virtual object GetObjectPropertyValue(object obj, string name)
        {
            Type t = obj.GetType();
            PropertyInfo p = t.GetProperty(name);
            object v = p.GetValue(obj, null);
            return v;
        }
        #endregion

        #region Common Properties
        public virtual bool ShowUpdate
        {
            get { return Operation != EntityOperation.None; }
        }

        /// <summary>
        /// 图标集合
        /// </summary>
        public IEnumerable<string> IconCollection
        {
            get
            {
                //return Helpers.XamlHelper.LoadXamlFromUri<ResourceDictionary>("/Corina.Cydee.Apphub;component/HomeUI/default.xaml");
                StreamResourceInfo rd = Application.GetResourceStream(new Uri("/Corina.Cydee.Apphub;Component/Themes/Icons.xaml", UriKind.RelativeOrAbsolute));
                ResourceDictionary dictionary = (ResourceDictionary)XamlReader.Load(new StreamReader(rd.Stream).ReadToEnd());

                var coll = dictionary.Where(r => r.Key.ToString().StartsWith("ICON_"));

                foreach (KeyValuePair<object, object> kvp in coll)
                {
                    yield return kvp.Key.ToString();
                }
            }
        }

        #region Enum collections
        public IEnumerable<PlatformTypeValue> PlatformCollection
        {
            get
            {
                return EnumHelper.GetEnumValues<PlatformTypeValue>();
            }
        }

        public IEnumerable<AccountTypeValue> AccountTypeCollection
        {
            get
            {
                return EnumHelper.GetEnumValues<AccountTypeValue>();
            }
        }
        #endregion

        protected bool IsDesignMode
        {
            get
            {
                return DesignerProperties.IsInDesignTool;//(bool)DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof(FrameworkElement)).Metadata.DefaultValue;
            }
        }

        private bool _isbusy = false;
        public virtual bool IsBusy
        {
            get { return _isbusy; }
            set
            {
                _isbusy = value;
                RaisePropertyChanged(() => IsBusy);
            }
        }

        private EntityOperation _operation = EntityOperation.None;
        public EntityOperation Operation
        {
            get { return _operation; }
            set
            {
                _operation = value;
                RaisePropertyChanged(() => Operation);
                OperationChanged();
            }
        }
        #endregion
        
        #region Current Account
        protected string Account
        {
            get
            {
                return DataContext.IsValid ? DataContext.CurrentAccount.Account : string.Empty;
            }
        }

        protected string Password
        {
            get
            {
                return DataContext.IsValid ? DataContext.CurrentAccount.Password : string.Empty;
            }
        } 
        #endregion

        #region Pagination
        private int _index = 1;
        public int Index
        {
            get { return _index; }
            set
            {
                _index = value;
                RaisePropertyChanged(() => Index);
                CurrentIndexChanged();
                RaisePropertyChanged(() => FirstPageCommand);
                RaisePropertyChanged(() => PreviousPageCommand);
                RaisePropertyChanged(() => NextPageCommand);
                RaisePropertyChanged(() => LastPageCommand);
            }
        }

        private int _itemsCount = 0;
        public int ItemsCount
        {
            get { return _itemsCount; }
            set
            {
                _itemsCount = value;
                RaisePropertyChanged(() => ItemsCount);
                RaisePropertyChanged(() => PagesCount);
                RaisePropertyChanged(() => FirstPageCommand);
                RaisePropertyChanged(() => PreviousPageCommand);
                RaisePropertyChanged(() => NextPageCommand);
                RaisePropertyChanged(() => LastPageCommand);
            }
        }

        public int PagesCount
        {
            get
            {
                return ItemsCount > 0 ? ((ItemsCount + 19) / 20) : 1;
            }
        }

        public ICommand FirstPageCommand
        {
            get
            {
                return new GenericCommand()
                {
                    CanExecuteCallback = delegate { return Index > 1; },
                    ExecuteCallback = delegate
                    {
                        Index = 1;
                    }
                };
            }
        }

        public ICommand PreviousPageCommand
        {
            get
            {
                return new GenericCommand()
                {
                    CanExecuteCallback = delegate { return Index > 1; },
                    ExecuteCallback = delegate
                    {
                        Index--;
                    }
                };
            }
        }

        public ICommand NextPageCommand
        {
            get
            {
                return new GenericCommand()
                {
                    CanExecuteCallback = delegate { return Index < PagesCount; },
                    ExecuteCallback = delegate
                    {
                        Index++;
                    }
                };
            }
        }

        public ICommand LastPageCommand
        {
            get
            {
                return new GenericCommand()
                {
                    CanExecuteCallback = delegate { return Index < PagesCount; },
                    ExecuteCallback = delegate
                    {
                        Index = PagesCount;
                    }
                };
            }
        }
        #endregion
    }
}
